package deanandjames.image;

import java.awt.image.BufferedImage;

public class PlayerImage {
	private final int animationPeriod;
	private long animationTotalTime;
	private boolean ignoreUpdates;
	private final String imageName;
	private int imagePosition;
	private final ImageLoader imagesLoader;
	private boolean isRepeating;
	private int numberOfImages;
	private PlayerImageWatcher playerWatcher = null;
	private double sequenceDurationSeconds;
	private int showPeriod;

	public PlayerImage(String imageName, int animationPeriod, double sequenceDuration, boolean isRepeating, ImageLoader imagesLoader) {
		this.imageName = imageName;
		this.animationPeriod = animationPeriod;
		sequenceDurationSeconds = sequenceDuration;
		this.isRepeating = isRepeating;
		this.imagesLoader = imagesLoader;
		animationTotalTime = 0L;
		if (sequenceDurationSeconds < 0.5) {
			System.out.println("Warning: minimum sequence duration is 0.5 sec. Increasing to 0.5");
			sequenceDurationSeconds = 0.5;
		}
		if (!this.imagesLoader.isLoaded(this.imageName)) {
			System.out.println(this.imageName + " is not known by the ImagesLoader");
			numberOfImages = 0;
			imagePosition = -1;
			ignoreUpdates = true;
		} else {
			numberOfImages = this.imagesLoader.numImages(this.imageName);
			imagePosition = 0;
			ignoreUpdates = false;
			showPeriod = (int) (1000 * sequenceDurationSeconds / numberOfImages);
		}
	}

	public BufferedImage getCurrentImage() {
		if (numberOfImages != 0) {
			return imagesLoader.getImage(imageName, imagePosition);
		} else {
			return null;
		}
	}

	public void restartAt(int newImagePosition) {
		if (numberOfImages != 0) {
			if (newImagePosition < 0 || newImagePosition > numberOfImages - 1) {
				System.out.println("Out of range restart, starting at 0");
				newImagePosition = 0;
			}
			imagePosition = newImagePosition;
			animationTotalTime = (long) imagePosition * showPeriod;
			ignoreUpdates = false;
		}
	}

	public void setWatcher(PlayerImageWatcher playerWatcher) {
		this.playerWatcher = playerWatcher;
	}

	public void stop() {
		ignoreUpdates = true;
	}

	public void update() {
		if (!ignoreUpdates) {
			animationTotalTime = (animationTotalTime + animationPeriod) % (long) (1000 * sequenceDurationSeconds);
			imagePosition = (int) (animationTotalTime / showPeriod);
			if (imagePosition == numberOfImages - 1 && !isRepeating) {
				ignoreUpdates = true;
				if (playerWatcher != null) {
					playerWatcher.sequenceEnded(imageName);
				}
			}
		}
	}
}
